Виджеты. Spacer Expanded
➡️ Скачать презентацию. Гибкие Виджеты
➡️ Ссылка на репозиторий с кодом этого урока
Гибкие виджеты Flexible() и Expanded()
Flutter виджеты Row и Column по умолчанию размещают свои дочерние элементы с фиксированными размерами. Это может привести к проблемам, таким как переполнение экрана, если размеры дочерних элементов превышают доступное пространство.
Для решения этой проблемы используются гибкие виджеты Flexible и Expanded.
Фиксированные виджеты имеют неизменные размеры, которые не могут динамически изменяться в зависимости от доступного пространства.
Гибкие виджеты могут изменять свои размеры в зависимости от доступного пространства и свойств flex и fit.
Добавим в файл expanded_widget.dart новый виджет ExpandedExample()
class ExpandedExample extends StatelessWidget {
const ExpandedExample({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[400],
child: Row(
children: [
],
),
);
}
}
⭕ Чтобы отобразить этот виджет на экране, не забудем в main.dart передать в внутри виджета MyApp() в параметр body виджет ExpandedExample()
Для иллюстрации примера гибких виджетов, добавим еще один виджет, который будет представлять из себя цветной прямоугольник.
Добавим в файл expanded_widget.dart новый виджет ColorBox()
class ColorBox extends StatelessWidget {
final double width, height;
final Color? color;
const ColorBox({super.key,
required this.width,
required this.height,
this.color,
});
@override
Widget build(BuildContext context) {
return Container(
width: width,
height: height,
decoration: BoxDecoration(
color: color,
),
);
}
}
Теперь внутри виджета ExpandedExample() в строке Row() вставим три таких штуки и закрасим в разные цвета
class ExpandedExample extends StatelessWidget {
const ExpandedExample({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[400],
child: Row(
children: [
ColorBox(width: 100, height: 100, color: Colors.red[400]),
ColorBox(width: 100, height: 100, color: Colors.green[400]),
ColorBox(width: 100, height: 100, color: Colors.blue[400]),
],
),
);
}
}

В данном примере мы используем фиксированные виджеты, с жестко заданными размерами. Но чаще всего современные интерфейсы должны адаптироваться под разные размеры экранов и растягивать/сжимать свои элементы, при этом не ломая интерфейс.
Виджет Expanded() позволяет растягивать виджет на всё доступное пространство.
Также игнорирует ширину дочернего элемента при изменении размеров.
Обернем каждый виджет, Зеленый и Синий в виджет Expanded()
В результате у каждого из них ширина равноценного растянется на всё доступное пространство.
class ExpandedExample extends StatelessWidget {
const ExpandedExample({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[400],
child: Row(
children: [
ColorBox(width: 100, height: 100, color: Colors.red[400]),
Expanded(
child: ColorBox(
width: 100,
height: 100,
color: Colors.green[400],
),
),
Expanded(
child: ColorBox(
width: 100,
height: 100,
color: Colors.blue[400],
),
),
],
),
);
}
}
.png)
.png)
Если теперь пробовать менять размеры фиксированного красного виджета, то синий и зеленый буду также пропорционально увеличиваться или уменьшаться автоматически. Например, сделаем ширину красного в 300 едениц
.png)
Что значит 300 единиц?
Размеры элементов задаются в логических пикселях (logical pixels)
Независимые от устройства пиксели device-independent pixels или dp
Flutter вместо нас, в зависимости от размера экрана, посчитает реальное значение пикселей.
Виджет Expanded() в качестве параметра принимает flex, который указывает долю занимаемого пространства.
Если в Row или Column находятся несколько гибких виджетов, их доли рассчитываются как сумма значений flex.
Например, если у одного виджета flex: 1, а у другого flex: 2, то первый получит 1/3 доступного пространства, а второй — 2/3.
Expanded(
flex: 1,
child: ColorBox(
width: 100,
height: 100,
color: Colors.green[400],
),
),
Expanded(
flex: 2,
child: ColorBox(
width: 100,
height: 100,
color: Colors.blue[400],
),
),
.png)
Flexible
Виджет Flexible делает всё тоже самое, но зависит от параметра fit
-
FlexFit.loose: Виджет сохраняет свои минимальные размеры, но может использовать дополнительное пространство (по умолчанию) -
FlexFit.tight: Виджет растягивается на всё доступное пространство (Expanded)Также игнорирует ширину дочернего элемента при изменении размеров
ColorBox(width: 100, height: 100, color: Colors.red[400]),
Flexible(
child: ColorBox(
width: 100,
height: 100,
color: Colors.green[400],
),
),
Flexible(
child: ColorBox(
width: 100,
height: 100,
color: Colors.blue[400],
),
),
.png)